在 GitLab CI 中,流水線上每道關卡每個工作順利執行與否,都是控制著整條流水線如何進行的依據關鍵之一;工作可能因為當下的環境因素無法執行,但重新執行即可;也有可能執行時間超過預期想像,導致流水線執行時間過長,那麼這些因素該怎麼控制呢?
retry
有些時候部分工作的 GitLab Runner 在承接工作之後,可能因為 Runner 當下的一時的環境因素,一時之間無法正確的執行工作,這時候通常會嘗試著手動重新執行該工作確認,而 GitLab CI 可以怎麼設定工作自動重新執行呢?
在 GitLab CI 中,系統在 GitLab 9.5 之後即提供了 retry
這個參數,並且在 GitLab 11.5 之後擴充了參數功能,增加了判斷條件的機制,首先先來看第一個 retry
的例子:
retry-job:
image: ubuntu:20.04
script:
- echo 'Try Retry Feature'
- exit 1
retry: 2
上面的這個範例,刻意設計了一定會讓工作認為執行錯誤的情境,在 script
中,放置了 exit 1
的指令。其中 retry
參數代表這個工作在執行失敗後,最多會再重新執行 2 次。如底下的畫面,包含第一次執行之後失敗後,系統再次的重新嘗試了 2 次:
PS. retry
參數必須是一個大於等於 0 且 小於等於 2 的整數。
另外,當工作執行失敗啟用重新執行機制時,重新執行的 GitLab Runner 並不一定會是原本執行失敗的 Runner,因為重新執行機制啟動,會再將該工作加入到 GitLab Server 上的工作佇列中,等待可以 Runner 來領取工作,所以只要可以執行該工作的 Runner 都有機會領取到該工作。
retry
參數當只設定 retry
參數時,預設是只要有任何因素導致工作執行失敗,就會進行重新執行的動作。而可以限定一些因素嗎?在 GitLab 11.5 之後,新增了一些條件來限縮重新執行的條件,因此增加了兩個屬於 retry
的子參數:
max
: 最多可重新執行的次數when
: 工作執行失敗的條件,可以有多個條件以上方的範例改寫成增加兩個子參數的例子:
retry-job:
image: ubuntu:20.04
script:
- echo 'Try Retry Feature'
- exit 1
retry:
max: 2
when:
- always
如上方的這個例子,可以看出 when
參數,是允許設定多個條件的,那麼 when
支援哪些條件呢?
always
:工作發生任何錯誤 (預設值)。unknown_failure
:工作發生未知原因的錯誤。script_failure
:當工作的 script 發生錯誤。api_failure
:當使用 API 發生錯誤。stuck_or_timeout_failure
:當發生阻塞或執行時間過長。runner_system_failure
:當 Runner 的執行系統發生錯誤,如工作啟動失敗。missing_dependency_failure
:當設定相依的工作不存在。runner_unsupported
:當 Runner 無法支援時stale_schedule
:設定延遲執行的工作無法執行時job_execution_timeout
:當工作的 script 執行時間超過設定的最大執行時間時。archived_failure
: 當工作被封存而無法執行失敗時。unmet_prerequisites
:當工作的無法完成前置工作時。scheduler_failure
:當排程工作無法成功將工作交給 GitLab Runner 時。data_integrity_failure
:當判斷到結構完整性問題時。timeout
GitLab CI 的工作當下執行失敗,可以透過重新執行來驗證是否是永久性的錯誤,但工作如果設計在一定時間內執行成功才算成功,在 GitLab CI 中可以怎麼設定?在 GitLab 12.3 之後,提供了 timeout
這個參數,可以供設定該工作執行超過多久後,即判斷為執行失敗。如下第一個例子:
timeout-job:
image: ubuntu:20.04
script:
- echo 'Try timeout Feature'
- sleep 60
timeout: 30s
如上範例,在 script
中,設定了讓工作停止 60 秒,但 timeout
設定了超過 30 秒算超時,因此這一工作會執行失敗。
那麼,timeout
參數的時間設置格式有哪些呢?timeout
的時間設置格式,與之前談工作成品產出的過期時間格式是一致的,沒填單位時,預設一樣為秒,概略如下:
'42'
42 seconds
3 mins 4 sec
2 hrs 20 min
2h20min
6 mos 1 day
47 yrs 6 mos and 4d
3 weeks and 2 days
timeout
參數來覆寫預設的 timeout 時間。當然也可以透過專案上的「settings -> CI/CD -> General pipelines settings」中設定預設的超時時間。timeout
不得超過 GitLab Runner Server 上設定的 runner 最大可執行時間。當啟用 retry
機制時,可能就需要稍微思考一下,這個環境因素是否是可以避免的?retry
的設置是否真的是有必要的?畢竟,透過 retry
來再次執行就可能獲取成功,一個程度上也表示著,這個工作不是每次都可以成功,代表著它並非穩定的。
下一篇會繼續介紹關於在 GitLab CI 上關於終止工作的相關條件及參數。我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。